package com.tsk.example.api.controller;

import com.tsk.example.application.service.IRedisCluster;
import com.tsk.example.application.service.RedisLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @author: 黄嘉振
 * @create: 2023/6/19 10:05
 * @description:
 **/
@RestController
public class RedisClusterController {

    @Autowired
    @Qualifier("RedisClusterTemplateService")
    private IRedisCluster redisTemplateCluster;

    @PostMapping("/cluster/{key}")
    public String setData(@PathVariable("key") String key){
        System.out.println("set " + key);
        return redisTemplateCluster.set(key, key + " nice");
    }

    @GetMapping("/cluster/{key}")
    public String getData(@PathVariable("key") String key){
        String value = redisTemplateCluster.get(key);
        System.out.println(value);
        return value;
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/lock")
    public String lock(@RequestParam("key") String key, @RequestParam long releaseTime){
        RedisLock redisLock = new RedisLock(redisTemplate);
        String lock = redisLock.tryLock(key, releaseTime);
        return lock;
    }

    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("/redissontest")
    public String redissontest(@RequestParam("key") String key){
        RLock lock = redissonClient.getLock(key);
        // 业务处理
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(40);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
        return lock.getName();
    }

    @GetMapping("/testLock")
    public void testLock() {
        String key = "redisson-test";
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // 1、获取锁
                    RLock lock = redissonClient.getLock(key);
                    // 2、加锁
                    lock.lock();
                    // 指定解锁时间时，手动解锁会抛异常
//                    lock.lock(5, TimeUnit.SECONDS);
                    try {
                        System.out.println(System.currentTimeMillis() / 1000 + "加锁成功，执行后续代码，线程 ID：" + Thread.currentThread().getId());
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException e) {
                        System.out.println("执行异常：" + e);
                    } finally {
                        lock.unlock();
                        System.out.println(System.currentTimeMillis() / 1000 + " finally 解锁成功，线程 ID：" + Thread.currentThread().getId());
                    }
                }
            }, "redisson-test").start();
        }
    }
}
